---
id: segment
title: Add Segment
sidebar_label: Add Segment
---

Adding a new segment to Oh My Posh involves several steps to ensure proper integration. This guide walks you through creating a complete segment with all necessary files and registrations.

## Planning Your Segment

Before coding, define these key properties:

- **Segment ID**: A kebab-case identifier used in configs (e.g., `new-feature`)
- **Go Type Name**: PascalCase struct name for the code (e.g., `NewFeature`)
- **Category**: Choose from `cli`, `cloud`, `health`, `languages`, `music`, `scm`, `system`, or `web`
- **Description**: A clear one-line explanation of what the segment does
- **Properties**: List of configurable properties with types and defaults
- **Template**: Default template string (e.g., `{{ .Text }}`)

## Automated Setup (VS Code)

If you're using VS Code, you can use the automated segment creation command in VS Code Chat:

1. Open VS Code Chat (use the Chat icon in the sidebar or Command Palette: "Chat: Focus on Chat View")
3. Type `/segment` and follow the prompts
4. Provide your segment details when requested
5. The command will automatically create all necessary files and registrations

This automated approach ensures all files are created correctly with proper naming conventions and alphabetical ordering. If you prefer to create the segment manually or want to understand the process, continue with the manual steps below.

## Manual Setup Steps

## Step 1: Create the Go Implementation

Create a new file in `./src/segments/` named after your segment ID: `new_feature.go`.

```go
package segments

import (
	"github.com/jandedobbeleer/oh-my-posh/src/properties"
)

type NewFeature struct {
	Base

	// Fields that will be available in your template
	Text string
}

// Define constants for each configurable property
const (
	// EnableNewThing enables the new functionality
	EnableNewThing properties.Property = "enable_new_thing"
	// CustomText sets custom display text
	CustomText properties.Property = "custom_text"
)

func (n *NewFeature) Enabled() bool {
	// Set up data for the template using property values
	n.Text = n.props.GetString(CustomText, "default value")

	// Return true if the segment should be displayed
	// You can add logic here to determine if the segment is relevant
	return true
}

func (n *NewFeature) Template() string {
	return "{{ .Text }}"
}
```

**Key Guidelines:**
- Use UTF32 representation for icons (e.g., `"\uEFF1"`) instead of the actual icons
- Find icon codes at [Nerd Fonts Cheat Sheet][nf-icons]
- Keep the logic in `Enabled()` focused on data preparation and visibility determination

## Step 2: Register Your Segment

Edit `src/config/segment_types.go` to register your new segment:

### Add Gob Registration
In the `init()` function, add your segment to the gob registry (maintain alphabetical order):

```go
gob.Register(&segments.NewFeature{})
```

### Add Segment Constant
Add a constant for your segment type (maintain alphabetical order):

```go
// NEWFEATURE displays new feature information
NEWFEATURE SegmentType = "new-feature"
```

### Add to Segments Map
Register your segment in the `Segments` map (maintain alphabetical order):

```go
NEWFEATURE: func() SegmentWriter { return &segments.NewFeature{} },
```

## Step 3: Create Documentation

Create documentation at `website/docs/segments/[category]/[segment-id].mdx`:

```mdx
---
id: new-feature
title: New Feature
sidebar_label: New Feature
---

## What

Displays information about the new feature in your environment.

## Sample Configuration

import Config from '@site/src/components/Config.js';

<Config data={{
  "type": "new-feature",
  "style": "powerline",
  "powerline_symbol": "\uE0B0",
  "foreground": "#193549",
  "background": "#ffeb3b",
  "properties": {
    "enable_new_thing": true,
    "custom_text": "Hello World"
  }
}}/>

## Properties

| Name | Type | Description | Default |
| ---- | ---- | ----------- | ------- |
| `enable_new_thing` | `boolean` | Enables the new functionality | `false` |
| `custom_text` | `string` | Custom text to display | `""` |
```

## Step 4: Update Sidebar Navigation

Edit `website/sidebars.js` and add your documentation to the appropriate category (maintain alphabetical order):

```javascript
{
  type: "category",
  label: "🖥️ System", // or appropriate category
  collapsed: true,
  items: [
    // ... other segments
    "segments/system/new-feature",
    // ... more segments
  ]
}
```

## Step 5: Add JSON Schema Definition

Update `themes/schema.json` in two places:

### Add to Type Enum
In the segment type enum, add your segment ID (maintain alphabetical order):

```json
{
  "enum": [
    "angular",
    // ... other types
    "new-feature",
    // ... more types
  ]
}
```

### Add Schema Definition
In the `allOf` array, add your segment's property schema (maintain alphabetical order):

```json
{
  "if": {
    "properties": {
      "type": { "const": "new-feature" }
    }
  },
  "then": {
    "title": "New Feature Segment",
    "description": "https://ohmyposh.dev/docs/segments/system/new-feature",
    "properties": {
      "properties": {
        "properties": {
          "enable_new_thing": {
            "type": "boolean",
            "title": "Enable New Thing",
            "description": "Enables the new functionality",
            "default": false
          },
          "custom_text": {
            "type": "string",
            "title": "Custom Text",
            "description": "Custom text to display",
            "default": ""
          }
        }
      }
    }
  }
}
```

## Step 6: Add Tests

Create a test file `src/segments/new_feature_test.go` using table-driven tests:
```go
package segments

import (
	"testing"

	"github.com/jandedobbeleer/oh-my-posh/src/properties"
	"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
)

func TestNewFeature(t *testing.T) {
	cases := []struct {
		Case     string
		Template string
		CustomText string
		Expected string
	}{
		{Case: "default", CustomText: "", Expected: ""},
		{Case: "custom text", CustomText: "Hello", Expected: "Hello"},
	}

	for _, tc := range cases {
		t.Run(tc.Case, func(t *testing.T) {
			env := &mock.Environment{}
			props := properties.Map{
				CustomText: tc.CustomText,
			}

			segment := &NewFeature{}
			segment.Init(props, env)

			if !segment.Enabled() {
				t.Error("Expected segment to be enabled")
			}

			if segment.Text != tc.Expected {
				t.Errorf("Expected %s, got %s", tc.Expected, segment.Text)
			}
		})
	}
}
```

Look at [existing segment tests][tests] for more complex examples and inspiration.

## Step 7: Build and Test

Validate your implementation by building the project:

```shell
go build -v
```

Run your specific tests:

```shell
go test ./src/segments/new_feature_test.go
```

## Important Guidelines

### File Organization
- **Segment files**: `src/segments/[segment_id].go`
- **Test files**: `src/segments/[segment_id]_test.go`
- **Documentation**: `website/docs/segments/[category]/[segment-id].mdx`### Alphabetical Ordering
Maintain alphabetical order in:
- `init()` gob registrations in `segment_types.go`
- Segment type constants in `segment_types.go`
- Segments map entries in `segment_types.go`
- Schema type enum in `themes/schema.json`
- Schema `allOf` definitions in `themes/schema.json`
- Sidebar navigation items in `sidebars.js`

### Code Quality
- Use meaningful property names and constants
- Include descriptive comments for properties
- Keep `Enabled()` logic focused and efficient
- Use UTF32 codes for icons, not the actual icons
- Follow Go naming conventions (PascalCase for exported items)

### Documentation Standards
- Use `.mdx` extension for documentation files
- Include complete property tables with types, descriptions, and defaults
- Provide realistic sample configurations
- Keep line lengths under 120 characters
- Use proper headings and formatting

## Resources

- [Nerd Fonts Cheat Sheet][nf-icons] - Find icon UTF32 codes
- [Existing Tests][tests] - Examples for test patterns
- [Table-Driven Tests][tables] - Go testing best practices

## Create a Pull Request

Once you've completed all steps:

1. **Verify everything builds**: `go build -v`
2. **Run tests**: `go test ./src/segments/[your_segment]_test.go`
3. **Check formatting**: Ensure your code follows Go formatting standards
4. **Review checklist**: All files created/updated as described above
5. **Create PR**: Include a clear description of what your segment does

Be patient during the review process! 🏎

[segment-go]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/src/config/segment_types.go
[themes]: https://github.com/JanDeDobbeleer/oh-my-posh/tree/main/themes
[docs]: https://github.com/JanDeDobbeleer/oh-my-posh/tree/main/website/docs/segments
[sidebars]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/website/sidebars.js
[nf-icons]: https://www.nerdfonts.com/cheat-sheet
[tests]: https://github.com/JanDeDobbeleer/oh-my-posh/blob/main/src/segments/az_test.go
[tables]: https://blog.alexellis.io/golang-writing-unit-tests/
